import { MachineBase } from "@/Battle/StateMechine/MachineBase.js";

import { BattleEventType } from "@/Battle/Event/BattleEvent.js";
import CombatEventBus from "@/Battle/CombatEventBus.js";
import { CombatEventPool } from "@/Battle/Event/CombatEventPool.js";

import { BattleManager } from "@/managers/BattleManager.js";

export class ActionMachine extends MachineBase {
    constructor() {
        super();
        this.action=null;
        this.payload={action:null};
        this.subject=null;
        this.item=null;
        this.targets=null;
        this.addStateHandler('start', this.onActionPrepareRequest);
        this.addStateHandler('update',this.onUpdateAction);
        this.addStateHandler('end',this.onEndActionRequest);
    }

    onActionPrepareRequest = () => {
        this.wait();
        this.action = BattleManager.peekCurrentAction();
        this.payload.action=this.action;
       
        if (!this.action) {
            this.toback();
        } else {
            //输入或AI模块监听
            CombatEventBus.dispatch(
                CombatEventPool.newCombatEvent(
                    BattleEventType.Action.Prepare.Request,
                    this,
                    {
                        action:this.action
                    }
                ),
                this.prepareAction,
                this.onSkip
            );
        }

    }

    prepareAction = () => {
        CombatEventBus.dispatch(
            CombatEventPool.newCombatEvent(
                BattleEventType.Action.Prepare.Complete,
                this,
                this.payload
            ),
            this.onActionStartRequest,
            this.onSkip
        );
    }

    onActionStartRequest = () => {
        this.wait();
        //prepare准备好的action
        CombatEventBus.dispatch(
            CombatEventPool.newCombatEvent(
                BattleEventType.Action.Start.Request,
                this,
                this.payload
            ),
            this.startAction,
            this.onEndActionRequest
        );
    }

    startAction = () => {
        this.wait();
        this.action = BattleManager.getNextAction();//获取真正的action
        this.payload.action=this.action;
        if (this.action) {
            this.subject=this.action.subject();
            this.targets=this.action.targets();
            this.item=this.action.item();
            CombatEventBus.dispatch(
                CombatEventPool.newCombatEvent(
                    BattleEventType.Action.Start.Complete,
                    this,
                    {
                        action:this.action,
                        source:this.subject,
                        target:this.targets,
                        item:this.item
                    }
                ),
                this.startUpdate,
                this.onSkip
            );
        }

    }

    startUpdate=()=>{
        this.switchState('update');
    }

    onUpdateAction=()=>{
        if(!this.targets?.length){
            this.end();
            return;
        }
        this.wait();
        let target=this.targets.shift();
        CombatEventBus.dispatch(
            CombatEventPool.newCombatEvent(
                BattleEventType.Action.Update, 
                this,
                {
                    action:this.action,
                    source:this.subject,
                    target:target,
                    item:this.item
                }
            ),
            this.startUpdate,
            this.onSkip
        );
    }

    onEndActionRequest = () => {
        CombatEventBus.dispatch(
            CombatEventPool.newCombatEvent(
                BattleEventType.Action.End.Request, 
                this,
                this.payload
            ),
            this.endAction,
            this.onSkip
        );
    }

    endAction=()=>{
        CombatEventBus.dispatch(
            CombatEventPool.newCombatEvent(
                BattleEventType.Action.End.Complete, 
                this
            ),
            this.start,
            this.onSkip
        );
    }

    onSkip=()=>{
        this.toback();
        this.action=null;
        this.payload.action=null;
    }
}